from PyQt4 import QtGui, QtCore
from pipeit import GeneratorFactoriesPool_get_instance, \
	ComputationFactoriesPool_get_instance,      \
	FormatterFactoriesPool_get_instance,        \
	GeneratorFactoriesPool_free_instance,       \
	ComputationFactoriesPool_free_instance,     \
	FormatterFactoriesPool_free_instance,       \
	PipeStepXMLSerializer_get_instance,         \
	PipeStepXMLSerializer_free_instance,        \
	XMLPipeStepDescriptorBuilder_get_instance,  \
	XMLPipeStepDescriptorBuilder_free_instance, \
	PipelineLoader,                             \
	strlist, gestface_exception,                \
	IOKey
from main_win import  Ui_pypelab_mainwin
from pypelab.plugin import PluginManager
from pypelab import globals
from pypelab.ui.rendering import RenderProperties
from pypelab.pipeMeta import GUIPipeStepDescrBuilder
from pypelab.ui.pipeline import ComputationWidgetBuilder

class MainWindow(QtGui.QMainWindow):
	def __init__(self, parent=None):
		QtGui.QMainWindow.__init__(self, parent)		
		self.ui = Ui_pypelab_mainwin()
		self.ui.setupUi(self)
		
		# Filename of the last open pipeline file
		self.lastOpenFilename = None
		
		# computation list
		computationsFact = ComputationFactoriesPool_get_instance()
		availableComputationsList = strlist()
		computationsFact.list_all_classes(availableComputationsList)
			
		availableComputationsModel = QtGui.QStringListModel(availableComputationsList)
		self.ui.computationsListLW.addItems(availableComputationsModel.stringList())
		self.ui.pipe_work_area.register_draggable(self.ui.computationsListLW)
		
		# generators list
		generatorsFact = GeneratorFactoriesPool_get_instance()
		availableGeneratorsList = strlist()
		generatorsFact.list_all_classes(availableGeneratorsList)
			
		availableGeneratorsModel = QtGui.QStringListModel(availableGeneratorsList)
		self.ui.generatorsListLW.addItems(availableGeneratorsModel.stringList())
		self.generators_samples = {}
		for gen_name in availableGeneratorsList:
			self.generators_samples[gen_name] = GeneratorFactoriesPool_get_instance().build(gen_name)
			
		
		# formatters list
		formattersFact = FormatterFactoriesPool_get_instance()
		availableFormattersList = strlist()
		formattersFact.list_all_classes(availableFormattersList)
			
		availableFormattersModel = QtGui.QStringListModel(availableFormattersList)
		self.ui.formattersListLW.addItems(availableFormattersModel.stringList())
		
		#registering global elements
		globals.pipeWorkArea = self.ui.pipe_work_area
		globals.computationsListLW = self.ui.computationsListLW
		globals.generatorsListLW = self.ui.generatorsListLW
		globals.formattersListLW = self.ui.formattersListLW  
		
	def enableIO(self, work_area):
		if not work_area: return
		
		render_prop = RenderProperties()
		
		generatorsLW = self.ui.generatorsListLW
		in_types = work_area.widget().in_types
		out_types = work_area.widget().out_types
		for i in range(generatorsLW.count()):
			item = generatorsLW.item(i)
			type = self.generators_samples[item.text()].get_key().getType()
			brush = item.foreground()
			if not brush:
				brush = QtGui.QBrush()
			if type != '' and (type in in_types or type in out_types):
				item.setFlags(QtCore.Qt.ItemIsEnabled | 
							  QtCore.Qt.ItemIsSelectable | 
						  	  QtCore.Qt.ItemIsDragEnabled)
				if type in in_types and type in out_types:
					brush.setColor(render_prop.in_out_gen_color)
				elif type in in_types:
					brush.setColor(render_prop.in_gen_color)
				elif type in out_types:
					brush.setColor(render_prop.out_gen_color)	
			else:
				brush.setColor(render_prop.gen_disabled_color)
				item.setFlags(QtCore.Qt.ItemIsEnabled | 
							  QtCore.Qt.ItemIsSelectable) 
				
			item.setForeground(brush)
	
	def save(self):
		self.saveAs(self.lastOpenFilename)
			
	def saveAs(self, filename = None):
		import os
		if not filename: 
			filename = QtGui.QFileDialog.getSaveFileName(self, 'Save pipeline', os.path.expanduser('~'), "*.xml")
			if not filename: return
			
		self.lastOpenFilename = filename
		
		descrBuilder = GUIPipeStepDescrBuilder(globals.pipeWorkArea)
		descrSerializer = PipeStepXMLSerializer_get_instance()
		
		loader = PipelineLoader()
		loader.set_descr_builder(descrBuilder)
		loader.set_descr_consumer(descrSerializer)
		try:
			loader.load()
			descrSerializer.serialize(filename)
		except RuntimeError as err:
			logging.error(str(err))
		except gestface_exception as ex:
			logging.error(str(ex))
		except ValueError as err:
			logging.error(str(err))
		finally:						
			PipeStepXMLSerializer_free_instance()
			
			
	def open(self, filename = None):
		import os
		if not filename: 
			filename = QtGui.QFileDialog.getOpenFileName(self, 'Load pipeline', os.path.expanduser('~'), "*.xml")
			if not filename: return
			
		globals.pipeWorkArea.closeAllSubs()
			
		self.lastOpenFilename = filename
		descrBuilder = XMLPipeStepDescriptorBuilder_get_instance(filename) 
		descrSerializer = ComputationWidgetBuilder(globals.pipeWorkArea)
		
		loader = PipelineLoader()
		loader.set_descr_builder(descrBuilder)
		loader.set_descr_consumer(descrSerializer)
		try:
			loader.load()
		except RuntimeError as err:
			logging.error(str(err))
		except gestface_exception as ex:
			logging.error(str(ex))
		except ValueError as err:
			logging.error(str(err))
		finally:						
			XMLPipeStepDescriptorBuilder_free_instance()
			
	def close(self):
		box = QtGui.QMessageBox()
		box.setText("Are you sure you want to quit?")
		box.setStandardButtons(QtGui.QMessageBox.Yes | QtGui.QMessageBox.No)
		ret = box.exec_()
		if ret == QtGui.QMessageBox.Yes:
			super().close()
				

if __name__ == "__main__":
	import sys
	import logging
	
	# extensions to pipeit module
	IOKey.__hash__ = lambda k: "{0}.{1}".format(k.get_key(), k.getType() ).__hash__()
	
	configuration = "Debug"
	#configuration = "Release"
	
	logging.basicConfig(level=logging.INFO, format='%(levelname)s: %(asctime)-15s - %(message)s', stream=sys.stdout)
		
	pluginManager = PluginManager('/home/picci/workspace/gestface/gestface/dist/{0}/GNU-Linux-x86'.format(configuration))
	
	a = QtGui.QApplication(sys.argv)
	w = MainWindow()
	w.showMaximized()
	
	ret = a.exec_()
	
	GeneratorFactoriesPool_free_instance()
	ComputationFactoriesPool_free_instance()
	FormatterFactoriesPool_free_instance()
	
	sys.exit(ret)
	
	
